#include "../include/Particle.h"

#include <chrono>
#include <cmath>

#include <raylib.h>

#include "../include/datasingleton.h"

void Particle::update(const std::chrono::nanoseconds& delt) {
	m_duration += delt;

	if (m_radius < 0.003 * m_A && m_duration.count() * 1e-9 > 1.f) {
		m_state = ParticleState::Done;
		return;
	}
	
	float delt_seconds = delt.count() * 1e-9;

	float acceleration_x = -(m_dragCoefficient) * m_speed.x;
	float acceleration_y = -(m_dragCoefficient) * m_speed.y;
	float acceleration_z = -(m_dragCoefficient) * m_speed.z;

	// x = v0*t + 1/2*a*t^2
	float dx = m_speed.x * delt_seconds + 0.5 * acceleration_x * pow(delt_seconds, 2.0);
	float dy = m_speed.y * delt_seconds + 0.5 * acceleration_y * pow(delt_seconds, 2.0);
	float dz = m_speed.z * delt_seconds + 0.5 * acceleration_z * pow(delt_seconds, 2.0);

	m_pos.x += dx;
	m_pos.y += dy;
	m_pos.z += dz;

	// v = v0 + a*t
	m_speed.x += acceleration_x * delt_seconds;
	m_speed.y += acceleration_y * delt_seconds;
	m_speed.z += acceleration_z * delt_seconds;

	float t = m_duration.count() * 1e-9;

	// 以半径的变化设定颜色饱和度和亮度
	float A = m_A * 1.0f / (sqrtf(2 * PI) * m_theta); // 正态分布最大值
	float left_value = 0.5;
	float right_value = 1;
	float span = right_value - left_value;
	float hsvRatio = m_radius / A;
	float deltH = DataSingleton::instance()->h_k * t;
	Vector3 hsv = ColorToHSV(m_color);
	hsv.x += deltH;
	hsv.y = left_value + span * hsvRatio;
	hsv.z = left_value + span * hsvRatio;
	m_color = ColorFromHSV(hsv.x, hsv.y, hsv.z);

	// 半径以正态方程变化
	m_radius = A * expf(-powf(t - m_mu, 2.0) / (2 * powf(m_theta, 2.0)));
}

void Particle::draw() {
	DrawSphere(m_pos, m_radius, m_color);
}

